package ferp.core.game;

import java.util.Arrays;

/**
* User: user
* Date: 6/8/11 11:52 PM
*/
public class Input
{
  public static enum Offer {NO_OFFER, NO_MORE_TRICKS, REST_TRICKS_ARE_MINE, TRICKS_BY_CONTRACT_MINUS_3, TRICKS_BY_CONTRACT_MINUS_2, TRICKS_BY_CONTRACT_MINUS_1, TRICKS_BY_CONTRACT, TRICKS_BY_CONTRACT_PLUS_1, TRICKS_BY_CONTRACT_PLUS_2, TRICKS_BY_CONTRACT_PLUS_3}

  public static enum PoolUserChoice {SHOW_INITIAL_POSITION, REPLAY, CONTINUE}

  public int[] drop = new int[Game.TALON_SIZE];
  public Bid bid = Bid.pass();
  public int card;
  public boolean stand;
  public Offer offer;
  // stores relative score - relatively to number of rounds to be played
  public int score;
  // user choice on pool dialog upon set over
  public PoolUserChoice puc;
  // user choice for 'tricking 10' game (if checked)
  public boolean check10;
  // user choice to undo drop (either at contracting or misere confirm modes)
  public boolean undoDrop;

  public Input() {reset();}

  public void reset()
  {
    stand = false;
    offer = Offer.NO_OFFER;
    score = 0;
    puc = PoolUserChoice.CONTINUE;
    Arrays.fill(drop, 0);
    bid.reset();
    card = 0;
    check10 = false;
    undoDrop = false;
  }

  public static class Options
  {
    private static int bit = 1;

    // waiting flags
    public static final int WAIT_FOR_TOUCH = bit;
    public static final int WAIT_FOR_RESOLVER = (bit <<= 1);
    public static final int WAIT_FOR_POOL = (bit <<= 1);
    public static final int WAIT_FOR_CARD_ANIMATION = (bit <<= 1);
    public static final int WAIT_FOR_RESUMING = (bit <<= 1);
    public static final int WAIT_FOR_FAST_MOVING = (bit <<= 1);

    // input
    public static final int PASS = (bit <<= 1);
    public static final int WHIST_FULL = (bit <<= 1);
    public static final int WHIST_HALF = (bit <<= 1);
    public static final int PLAY = (bit <<= 1);
    public static final int MISERE = (bit <<= 1);
    public static final int DECLARE = (bit <<= 1);
    public static final int DROP = (bit <<= 1);
    public static final int STAND = (bit <<= 1);
    public static final int WITHOUT3 = (bit <<= 1);
    public static final int NO_MORE_TRICKS = (bit <<= 1);
    public static final int REST_TRICKS_ARE_MINE = (bit <<= 1);
    public static final int TRICKS_BY_CONTRACT = (bit <<= 1);
    public static final int TRICKS_BY_CONTRACT_MINUS_3 = (bit <<= 1);
    public static final int TRICKS_BY_CONTRACT_MINUS_2 = (bit <<= 1);
    public static final int TRICKS_BY_CONTRACT_MINUS_1 = (bit <<= 1);
    public static final int TRICKS_BY_CONTRACT_PLUS_1 = (bit <<= 1);
    public static final int TRICKS_BY_CONTRACT_PLUS_2 = (bit <<= 1);
    public static final int TRICKS_BY_CONTRACT_PLUS_3 = (bit <<= 1);
    public static final int WHIST_PASS = (bit <<= 1);

    // waiting flags (starting from 1.5.2 45)
    public static final int WAIT_FOR_TRICKING_10_CHECK = (bit <<= 1);

    // input flags (starting from 1.5.2 45)
    public static final int TRICKING_10_CHECK = (bit <<= 1);
    public static final int TRICKING_10_CONFIRM = (bit <<= 1);

    // input flags (starting from 1.5.4 50)
    public static final int MISERE_CONFIRM = (bit <<= 1);

    public static final int WAIT_FOR_INTRODUCTION = (bit <<= 1);

    public Bid bid = Bid.pass();
    // if not 0 designates player move possibilities
    public int hand;
    // human score
    public short score;

    public void set(int flag) {this.flag |= flag;}
    public boolean isHumanInputRequired() {return flag != 0;}
    public boolean isSet(int flag) {return (this.flag & flag) == flag;}
    public int flag() {return flag;}

    // clear options
    public void clear()
    {
      flag = 0;
      bid.reset();
      hand = 0;
      score = 0;
    }

    public void clear(int flag) {this.flag &= ~flag;}

    public boolean isOfferSet()
    {
      return isSet(Input.Options.TRICKS_BY_CONTRACT_PLUS_3) || isSet(Input.Options.TRICKS_BY_CONTRACT_PLUS_2) ||
             isSet(Input.Options.TRICKS_BY_CONTRACT_PLUS_1) || isSet(Input.Options.TRICKS_BY_CONTRACT) ||
             isSet(Input.Options.TRICKS_BY_CONTRACT_MINUS_1) || isSet(Input.Options.TRICKS_BY_CONTRACT_MINUS_2) ||
             isSet(Input.Options.TRICKS_BY_CONTRACT_MINUS_3) || isSet(Input.Options.NO_MORE_TRICKS) || isSet(Input.Options.REST_TRICKS_ARE_MINE);
    }

    private int flag;
  }
}
